﻿#region Regions

using System.Collections.Generic;

#endregion

namespace FMWare.Core.Base
{
	public abstract class IndexedCollection<T> : Collection<T> where T : IndexedItem, new()
	{
		#region Declarations

		private Dictionary<int, T> _indexView;

		#endregion

		#region Constructors

		protected IndexedCollection(int capacity) : base(capacity) {}

		#endregion

		#region Protected Properties

		protected bool IsPerson { get; set; }
		protected bool IsServer { get; set; }
		protected bool UseIndexView { get; set; }

		#endregion

		#region Internal Methods

		/// <summary>
		/// Finds the item with by the index.
		/// </summary>
		/// <param name="index">The index.</param>
		/// <returns></returns>
		internal T FindByIndex(int index)
		{
			if (_indexView.ContainsKey(index))
				return _indexView[index];
			return default(T);
		}

		/// <summary>
		/// Reads the data with the specified reader.
		/// </summary>
		/// <param name="reader">The reader.</param>
		internal override void Read(BinaryReader reader)
		{
			if (!IsPerson)
			{
				RecordCount = reader.ReadInt32();
				_indexView = new Dictionary<int, T>(RecordCount);
				_uniqueIdView = new Dictionary<int, T>(RecordCount);
			}

			for (int i = 0; i < RecordCount; i++)
			{
				T item = new T {IsServer = IsServer};
				item.Read(reader);
				if (item.Index != -1)
				{
					Add(item.UniqueId, item);
					if (UseIndexView && item.IsServer) _indexView.Add(item.Index, item);
				}
			}
		}

		/// <summary>
		/// Writes the data with specified writer.
		/// </summary>
		/// <param name="writer">The writer.</param>
		internal override void Write(BinaryWriter writer)
		{
			if (!IsPerson)
				writer.Write(Count);

			foreach (T item in Values)
			{
				item.IsServer = IsServer;
				item.Write(writer);
			}
		}

		#endregion
	}
}